package com.wn.sddfp.access.service.impl;
import java.time.LocalDateTime;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wn.sddfp.access.entity.TradeLog;
import com.wn.sddfp.access.mapper.TradeLogMapper;
import com.wn.sddfp.access.service.ITradeLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wn.sddfp.common.model.dto.bank.BankCardAddDTO;
import com.wn.sddfp.common.model.dto.bank.BankReqDto;
import com.wn.sddfp.common.model.dto.bank.BaseResult;
import com.wn.sddfp.common.model.dto.bank.SignatureDto;
import com.wn.sddfp.common.model.dto.borrow.BorrowSyncRecordVo;
import com.wn.sddfp.common.model.utils.EncryptUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

/**
 * <p>
 * 托管系统交易记录表 服务实现类
 * </p>
 *
 * @author yellow docker
 * @since 2024-07-31
 */
@Slf4j
@Service
public class TradeLogServiceImpl extends ServiceImpl<TradeLogMapper, TradeLog> implements ITradeLogService {



    //存储日志
    @SneakyThrows //处理异常的注解
    @Override
    public SignatureDto proxyBindCardLog(BankCardAddDTO bankCardAddDTO) {

        //1、创建日志
        TradeLog tradeLog = new TradeLog();

        //请求码
        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        // 用户绑卡的 字符
        tradeLog.setReqType("USER_BIND_CARD");
        //主题用户 (userId)
        tradeLog.setObjectId(bankCardAddDTO.getUserId());
        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());

        //&&&&&&&银行系统返回的数据 进行更新 当前这里进行默认就可以&&&&&&
        //数据同步
        tradeLog.setSynchronizeStatus(0);
        //确认时间
        tradeLog.setConfirmDate(LocalDateTime.now());
        //返回的数据
        tradeLog.setResponseData("");

        //2、存储日志
        save(tradeLog);

        //3、调用银行系统 返回数据
        // 返回结果 直接创建一个对象 返回结果
        SignatureDto signatureDto = new SignatureDto();
        signatureDto.setBankUrl("http://localhost:5600/bank/user");
        signatureDto.setPlatformNo("SDDFP");
        signatureDto.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        signatureDto.setReqCode(bankCardAddDTO.getReqCode());

        return signatureDto;
    }

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 银行托管代理服务
     * @param borrowSyncRecordVo
     * @return
     */
    @Override
    public BaseResult syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {

        //1、保存日志
        TradeLog tradeLog = new TradeLog();

        //流水号
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        //请求的类型
        tradeLog.setReqType("SYNC_BORROW");
        //主体  userId
        tradeLog.setObjectId(borrowSyncRecordVo.getUserId());
        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());
        //确认时间
        tradeLog.setConfirmDate(LocalDateTime.now());
        //同步状态默认是0  (银行返回结果 需要更新状态1 )
        tradeLog.setSynchronizeStatus(0);

        save(tradeLog);

        //银行返回结果更新的数据
//        tradeLog.setResponseData("");

        //2、远程调用银行 系统
        //2.1 请求基础路径；作为完成路径的一部分
        String url = "http://localhost:5600/service";
        //2.2 发送数据给银行系统  看银行系统
        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        // 请求数据:reqData
        // String url = "http://ip:5600/service?serviceName=SYNC_BORROW_RECODE&reqData=xxx";

        //2.3 请求数据 - 对象转换为JSON， 使用alibaba提供的fastjson工具类(银行托管也是使用fastjson)
        String str = JSON.toJSONString(borrowSyncRecordVo);
        //2.4 对象加密处理： str ---> Base64编码 ---> URL编码 ---> 目标str
        // str ---> Base64编码
        String base64Str = EncryptUtil.encodeUTF8StringBase64(str);
        // Base64编码 ---> URL编码
        String reqData = EncryptUtil.encodeURL(base64Str);

        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=" + reqData;
        log.info("发送数据的url:{}",url);

        // 银行系统使用的是 @RestController 把对象都转成 json 字符串
        //发送远程调用
        String respBody = restTemplate.getForObject(url, String.class);

        log.info("银行系统返回的数据:{}",respBody);
        // {"respData":{"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"}}
        BankReqDto bankReqDto = JSON.parseObject(respBody, BankReqDto.class);
        //拿到字符串解析
        BaseResult baseResult = JSON.parseObject(bankReqDto.getRespData(), BaseResult.class);
        log.info("银行系统返回的数据进行解析:{}",baseResult);
        String respMsg = baseResult.getRespMsg();
        //StringUtils.hasText() 字符串判空处理
        if (StringUtils.hasText(respMsg) && respMsg.equals("成功")){
            //更新确认时间
            tradeLog.setConfirmDate(LocalDateTime.now());
            //更新状态
            tradeLog.setSynchronizeStatus(1);
            //存储 银行系统返回的结果
            tradeLog.setResponseData(respBody);
            //银行系统返回结果后进行更新
            updateById(tradeLog);
        }
        //返回银行系统的结果
        return baseResult;
    }
}
